Qdrantのスナップショット保存先にS3バケットを指定してみた

Qdrantのスナップショット保存先にS3バケットを指定してみた

Clock Icon2024.10.23

リテールアプリ共創部@大阪の岩田です。

Qdrantには簡単にコレクションのスナップショットが取得できるという特徴があります。このスナップショットはデフォルトではQdrantが稼働しているマシンのローカルファイルシステムに保存されるのですが、設定ファイルを記述することでS3に保存することもできます。

このブログではQdrantのスナップショットをS3に保存する機能を試してみます。

環境

先日のブログで構築した環境を利用していきます。

https://dev.classmethod.jp/articles/install-qdrant-on-ec2-without-docker/

また、EC2インスタンスに設定したIAMロールにはS3関連の必要な権限を設定していることとします。

やってみる

それではさっそくS3へのスナップショット取得を試していきましょう。

スナップショットをS3に保存するには、保存先のS3バケット等を指定するために設定ファイルを記述する必要があります。

スナップショット関連の設定はstoragesnapshots_config配下に記述します。snapshots_storages3を指定することでスナップショットをS3に保存できます。さらにsnapshots_storages3を指定した場合は、s3_configというキー配下に以下の設定が記述可能になります。

  • bucket
  • region
  • access_key
  • secret_key
  • endpoint_url

それぞれの設定値の意味はキーの名前から推測できると思います。aws_session_tokenには対応していないのがポイントですね。

ちょっとソースを追ってみたんですが、設定はこのあたりで定義していました。

https://github.com/qdrant/qdrant/blob/9c20e9e27960228019b4606f137ca82b42fc3e66/lib/collection/src/common/snapshots_manager.rs#L35-L41

実際にS3に書き込む処理はobject_storeというクレートを利用していて、上記Structで指定した設定値をobject_store::aws::AmazonS3Builderに渡して利用するようです。

https://github.com/qdrant/qdrant/blob/9c20e9e27960228019b4606f137ca82b42fc3e66/lib/collection/src/common/snapshots_manager.rs#L64-L91

今回は以下のような設定ファイルを用意しました。

log_level: DEBUG

service:
  host: 0.0.0.0
  http_port: 6333
  grpc_port: 6334

storage:
  performance:
    max_search_threads: 4

  optimizers:
    flush_interval_sec: 5

    default_segment_number: 2

  handle_collection_load_errors: true
  snapshots_config:
    snapshots_storage: s3
    s3_config:
      bucket: <スナップショット保存先のS3バケット名>

access_keyとsecret_keyは指定していませんが、EC2にアタッチしているIAMロールの権限をうまく使ってくれることを期待したいとろこです。

設定ファイルの準備ができたのでqdrantを起動します。

./target/release/qdrant

http://<EC2のGIP>:6333/dashboard#にアクセスし、ダッシュボードからQuickstartのチュートリアルを実行し、コレクションを作成しておきます。

コレクションの準備ができたので、ダッシュボードのCollectionsからTake Snapshotを実行してみましょう。

コレクション一覧画面

スナップショット取得画面

Qdrantを実行しているターミナルに以下のようなログが出力されました。

2024-10-23T00:35:42.724603Z  INFO collection::collection::snapshots: Creating collection snapshot star_charts-1725973526092207-2024-10-23-00-35-42.snapshot into "./snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-35-42.snapshot"
2024-10-23T00:35:42.783341Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/6c584b07-1f68-4c8d-bdc6-7c49b5dd0fce"
2024-10-23T00:35:42.803042Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/0fd931d0-61d1-46c7-9386-26457bf8252e"
2024-10-23T00:35:42.831097Z  INFO object_store::aws::builder: Using Instance credential provider
2024-10-23T00:35:42.834634Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T00:35:42.835661Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T00:35:42.839806Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T00:35:42.840728Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T00:35:43.131525Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T00:35:43.142284Z  INFO actix_web::middleware::logger: <アクセス元GIP> "POST /collections/star_charts/snapshots HTTP/1.1" 200 146 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.417870

ダッシュボードを確認すると無事にスナップショットが取得できていました。

取得済みのスナップショット一覧

S3のマネコンからもスナップショットが確認できました。

S3のマネコンから確認したスナップショットの詳細

S3関連の権限が不足しているとどうなるか確認してみる

せっかくなのでIAMロールにS3関連の権限が不足しているとどうなるか確認してみました。

スナップショットの一覧表示

まずはS3関連の権限を全て削除した状態で確認

スナップショット一覧表示時のエラー

Internal Server Errorが表示されました。

ログには以下のようなエラーが出力されていました。

2024-10-23T00:51:14.755994Z  INFO actix_web::middleware::logger: <アクセス元のGIP> "GET /collections/star_charts/cluster HTTP/1.1" 200 159 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.000217
2024-10-23T00:51:14.786604Z ERROR qdrant::actix::helpers: Error processing request: Service internal error: Failed to list snapshots: Generic S3 error: Error performing list request: Client error with status 403 Forbidden: <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>User: arn:aws:sts::<AWSアカウントID>:assumed-role/qdrant-role/i-00bf5989c46de63aa is not authorized to perform: s3:ListBucket on resource: "arn:aws:s3:::<S3バケット名>" because no identity-based policy allows the s3:ListBucket action</Message><RequestId>T1W6GZ1XSTF85Q3Q</RequestId><HostId>ixbMroj8TjbozjpXrhbheDj9u5OFLN3KgZEKL3Edpmwt8+/9y6gBv45PPrBk+YEUk5ahYFRRhnM=</HostId></Error>
2024-10-23T00:51:14.786818Z  INFO actix_web::middleware::logger: <アクセス元のGIP> "GET /collections/star_charts/snapshots HTTP/1.1" 500 475 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.038616

s3:ListBucketの権限が無いとのことなので、s3:ListBucketの権限を付与した後に再度トライしてみます。今度はスナップショットの一覧は表示できました。

スナップショットの取得

続いて「TAKE SNAPSHOT」でスナップショットの取得を試みましたが、以下のエラーで失敗しました。

2024-10-23T00:55:44.524139Z  INFO collection::collection::snapshots: Creating collection snapshot star_charts-1725973526092207-2024-10-23-00-55-44.snapshot into "./snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-55-44.snapshot"
2024-10-23T00:55:44.579451Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/6c584b07-1f68-4c8d-bdc6-7c49b5dd0fce"
2024-10-23T00:55:44.597493Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/0fd931d0-61d1-46c7-9386-26457bf8252e"
2024-10-23T00:55:44.623775Z  INFO object_store::aws::builder: Using Instance credential provider
2024-10-23T00:55:44.626643Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T00:55:44.627335Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T00:55:44.627822Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T00:55:44.628345Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T00:55:44.670279Z ERROR qdrant::actix::helpers: Error processing request: Service internal error: failed to store snapshot archive to /home/ec2-user/qdrant/./storage/tmp/star_charts-1725973526092207-2024-10-23-00-55-44.snapshot-arc-3zKS4f: Service internal error: Failed to put multipart: The operation lacked the necessary privileges to complete for path snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-55-44.snapshot: Client error with status 403 Forbidden: <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>User: arn:aws:sts::<AWSアカウントID>:assumed-role/qdrant-role/i-00bf5989c46de63aa is not authorized to perform: s3:PutObject on resource: "arn:aws:s3:::<S3バケット名>/snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-55-44.snapshot" because no identity-based policy allows the s3:PutObject action</Message><RequestId>QYV3PPMQ920FGV0V</RequestId><HostId>Py6d09LtDdVcepfX2ljKwT1c0nW3Xg7cpD6kmHA7aYiEKygWiw0P/OGXK+jMuN6NKaQ4ZBvYPks=</HostId></Error>
2024-10-23T00:55:44.670493Z  INFO actix_web::middleware::logger: <アクセス元GIP> "POST /collections/star_charts/snapshots HTTP/1.1" 500 609 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.146518

今度はs3:PutObjectの権限不足によって失敗しているようです。s3:PutObjectの権限を付与して再トライします。

2024-10-23T01:41:49.649262Z  INFO collection::collection::snapshots: Creating collection snapshot star_charts-1725973526092207-2024-10-23-01-41-49.snapshot into "./snapshots/star_charts/star_charts-1725973526092207-2024-10-23-01-41-49.snapshot"
2024-10-23T01:41:49.706332Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/0fd931d0-61d1-46c7-9386-26457bf8252e"
2024-10-23T01:41:49.732051Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/6c584b07-1f68-4c8d-bdc6-7c49b5dd0fce"
2024-10-23T01:41:49.755223Z  INFO object_store::aws::builder: Using Instance credential provider
2024-10-23T01:41:49.759264Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:41:49.760349Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:41:49.761307Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:41:49.761993Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T01:41:49.998938Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T01:41:50.007825Z ERROR qdrant::actix::helpers: Error processing request: Service internal error: failed to store snapshot archive to /home/ec2-user/qdrant/./storage/tmp/star_charts-1725973526092207-2024-10-23-01-41-49.snapshot-arc-qMbtmS: Service internal error: Failed to get head: The operation lacked the necessary privileges to complete for path snapshots/star_charts/star_charts-1725973526092207-2024-10-23-01-41-49.snapshot: Client error with status 403 Forbidden: No Body
2024-10-23T01:41:50.008359Z  INFO actix_web::middleware::logger: <アクセス元のGIP> "POST /collections/star_charts/snapshots HTTP/1.1" 500 287 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.359175

今度はClient error with status 403 Forbidden: No Bodyとのことです。具体的に何の権限不足かは分かりませんが、このエラーが出たときはS3上にオブジェクトは保存されていました。つまりPutObject成功後に何かしらの操作を行い、その操作に失敗したと考えられそうです。ということでs3:GetObjectあたりかな?と予想して権限を付与して再トライします。

2024-10-23T01:49:41.982639Z  INFO collection::collection::snapshots: Creating collection snapshot star_charts-1725973526092207-2024-10-23-01-49-41.snapshot into "./snapshots/star_charts/star_charts-1725973526092207-2024-10-23-01-49-41.snapshot"
2024-10-23T01:49:42.038668Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/0fd931d0-61d1-46c7-9386-26457bf8252e"
2024-10-23T01:49:42.064042Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/6c584b07-1f68-4c8d-bdc6-7c49b5dd0fce"
2024-10-23T01:49:42.085963Z  INFO object_store::aws::builder: Using Instance credential provider
2024-10-23T01:49:42.088681Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:49:42.090754Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:49:42.091308Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:49:42.091887Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T01:49:42.280237Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T01:49:42.293251Z  INFO actix_web::middleware::logger: <アクセス元のGIP> "POST /collections/star_charts/snapshots HTTP/1.1" 200 146 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.310688

今度は無事に成功しました!

スナップショットの削除

あとはスナップショットの削除も試しておきましょう。

2024-10-23T01:52:44.279980Z  INFO object_store::aws::builder: Using Instance credential provider
2024-10-23T01:52:44.283507Z  INFO storage::content_manager::snapshots: Deleting collection snapshot "./snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-35-42.snapshot"
2024-10-23T01:52:44.283591Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:52:44.284288Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:52:44.284771Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:52:44.285511Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T01:52:44.311092Z ERROR qdrant::actix::helpers: Error processing request: Service internal error: Failed to delete snapshot: The operation lacked the necessary privileges to complete for path snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-35-42.snapshot: Client error with status 403 Forbidden: <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>User: arn:aws:sts::<AWSアカウントID>:assumed-role/qdrant-role/i-00bf5989c46de63aa is not authorized to perform: s3:DeleteObject on resource: "arn:aws:s3:::<S3バケット名>/snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-35-42.snapshot" because no identity-based policy allows the s3:DeleteObject action</Message><RequestId>G9S4A0H6PD864V3C</RequestId><HostId>r+VE8hWLRIQr0cqMfIdLUpm0mooOBVjDqgtV7P9c+8HG64JAEB1iQJKzUQ65dZEFnuTY7maVvas=</HostId></Error>
2024-10-23T01:52:44.311291Z  INFO actix_web::middleware::logger: <アクセス元GIP> "DELETE /collections/star_charts/snapshots/star_charts-1725973526092207-2024-10-23-00-35-42.snapshot HTTP/1.1" 500 556 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.031377

今度はs3:DeleteObjectが不足しているようなので権限を付与して再トライ...

スナップショットの削除に成功

無事削除に成功しました。

最終的にEC2用のIAMロールに割り当てた許可ポリシーは以下の通りでした。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::<S3バケット名>"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::<S3バケット名>/*"
        }
    ]
}

まとめ

Qdrantのスナップショット機能を試してみました。やはりS3に保存できると安心感がありますね。

もし自前でQdrantのクラスタを運用することになったら、S3にスナップショットを保存するよう設定しておきたいところです。

参考

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.